<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Houzz爬虫任务管理器</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css" rel="stylesheet">
    <style>
        .status-card {
            transition: all 0.3s ease;
        }
        .status-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
        }
        .progress-bar {
            transition: width 0.3s ease;
        }
        .log-container {
            max-height: 300px;
            overflow-y: auto;
            background-color: #f8f9fa;
            border-radius: 0.375rem;
        }
        .log-entry {
            padding: 0.5rem;
            border-bottom: 1px solid #dee2e6;
            font-family: 'Courier New', monospace;
            font-size: 0.875rem;
        }
        .log-entry:last-child {
            border-bottom: none;
        }
        .btn-group-custom {
            display: flex;
            gap: 0.5rem;
        }
        .task-form {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border-radius: 1rem;
            padding: 2rem;
        }
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 1rem;
        }
    </style>
</head>
<body class="bg-light">
    <div class="container-fluid py-4">
        <!-- 页面标题 -->
        <div class="row mb-4">
            <div class="col-12">
                <h1 class="text-center text-primary">
                    <i class="bi bi-robot"></i> Houzz爬虫任务管理器
                </h1>
                <p class="text-center text-muted">管理爬虫任务，监控进度，导出数据</p>
            </div>
        </div>

        <!-- 任务控制面板 -->
        <div class="row mb-4">
            <div class="col-12">
                <div class="card task-form">
                    <div class="card-body">
                        <h4 class="card-title mb-4">
                            <i class="bi bi-play-circle"></i> 任务控制
                        </h4>
                        
                        <form id="taskForm">
                            <div class="row">
                                <div class="col-md-6 mb-3">
                                    <label for="categoryUrl" class="form-label">类目URL</label>
                                    <input type="url" class="form-control" id="categoryUrl" 
                                           placeholder="https://www.houzz.com/professionals/architect/probr0-bo~t_11784"
                                           required>
                                </div>
                                <div class="col-md-3 mb-3">
                                    <label for="startPage" class="form-label">起始页</label>
                                    <input type="number" class="form-control" id="startPage" 
                                           value="1" min="1" max="1000" required>
                                </div>
                                <div class="col-md-3 mb-3">
                                    <label for="endPage" class="form-label">结束页</label>
                                    <input type="number" class="form-control" id="endPage" 
                                           value="10" min="1" max="1000" required>
                                </div>
                            </div>
                            
                            <div class="btn-group-custom">
                                <button type="submit" class="btn btn-success btn-lg" id="startBtn">
                                    <i class="bi bi-play-fill"></i> 启动任务
                                </button>
                                <button type="button" class="btn btn-danger btn-lg" id="stopBtn" disabled>
                                    <i class="bi bi-stop-fill"></i> 停止任务
                                </button>
                                <button type="button" class="btn btn-info btn-lg" id="exportBtn" disabled>
                                    <i class="bi bi-download"></i> 导出数据
                                </button>
                                <button type="button" class="btn btn-warning btn-lg" id="clearBtn">
                                    <i class="bi bi-trash"></i> 清空任务
                                </button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>

        <!-- 任务状态和进度 -->
        <div class="row mb-4">
            <div class="col-12">
                <div class="card">
                    <div class="card-header">
                        <h5 class="mb-0">
                            <i class="bi bi-activity"></i> 任务状态
                        </h5>
                    </div>
                    <div class="card-body">
                        <div class="stats-grid">
                            <div class="status-card card border-primary">
                                <div class="card-body text-center">
                                    <h6 class="card-title text-primary">任务状态</h6>
                                    <h4 id="taskStatus" class="text-primary">待机中</h4>
                                </div>
                            </div>
                            
                            <div class="status-card card border-info">
                                <div class="card-body text-center">
                                    <h6 class="card-title text-info">成功页数/总页数</h6>
                                    <h4 id="successPagesRatio" class="text-info">0/0</h4>
                                </div>
                            </div>
                            
                            <div class="status-card card border-success">
                                <div class="card-body text-center">
                                    <h6 class="card-title text-success">成功详情数</h6>
                                    <h4 id="successDetails" class="text-success">0</h4>
                                </div>
                            </div>
                            
                            <div class="status-card card border-warning">
                                <div class="card-body text-center">
                                    <h6 class="card-title text-warning">失败详情数</h6>
                                    <h4 id="failedDetails" class="text-warning">0</h4>
                                </div>
                            </div>
                            
                            <div class="status-card card border-secondary">
                                <div class="card-body text-center">
                                    <h6 class="card-title text-secondary">总详情数</h6>
                                    <h4 id="totalDetails" class="text-secondary">0</h4>
                                </div>
                            </div>
                        </div>
                        
                        <!-- 进度条 -->
                        <div class="mt-4">
                            <label class="form-label">整体进度</label>
                            <div class="progress" style="height: 25px;">
                                <div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated" 
                                     role="progressbar" style="width: 0%">
                                    <span id="progressText">0%</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 实时日志 -->
        <div class="row">
            <div class="col-12">
                <div class="card">
                    <div class="card-header d-flex justify-content-between align-items-center">
                        <h5 class="mb-0">
                            <i class="bi bi-terminal"></i> 实时日志
                        </h5>
                        <button class="btn btn-sm btn-outline-secondary" id="clearLogBtn">
                            <i class="bi bi-trash"></i> 清空日志
                        </button>
                    </div>
                    <div class="card-body p-0">
                        <div id="logContainer" class="log-container">
                            <div class="log-entry text-muted">
                                <i class="bi bi-info-circle"></i> 系统就绪，等待任务启动...
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 下载模态框 -->
    <div class="modal fade" id="downloadModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">
                        <i class="bi bi-download"></i> 数据导出
                    </h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <div class="alert alert-success">
                        <i class="bi bi-check-circle"></i> 数据导出成功！
                    </div>
                    <p>文件包含 <strong id="exportCount">0</strong> 条记录</p>
                    <p>文件名: <code id="exportFilename">houzz_data.xlsx</code></p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
                    <a id="downloadLink" class="btn btn-primary" href="#" download>
                        <i class="bi bi-download"></i> 下载文件
                    </a>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // API路由前缀
        const SPIDER_NAME = '{{ spider_name }}';
        const API_PREFIX = '/api/task';  // 单爬虫模式，不需要spider_name前缀
        
        let statusInterval;
        let isTaskRunning = false;

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function() {
            initializeEventListeners();
            startStatusUpdates();
        });

        function initializeEventListeners() {
            // 任务表单提交
            document.getElementById('taskForm').addEventListener('submit', function(e) {
                e.preventDefault();
                startTask();
            });

            // 停止任务
            document.getElementById('stopBtn').addEventListener('click', stopTask);

            // 导出数据
            document.getElementById('exportBtn').addEventListener('click', exportData);

            // 清空任务
            document.getElementById('clearBtn').addEventListener('click', clearTaskData);

            // 清空日志
            document.getElementById('clearLogBtn').addEventListener('click', clearLogs);
        }

        function startTask() {
            const categoryUrl = document.getElementById('categoryUrl').value;
            const startPage = parseInt(document.getElementById('startPage').value);
            const endPage = parseInt(document.getElementById('endPage').value);

            if (!categoryUrl) {
                alert('请输入类目URL');
                return;
            }

            if (startPage > endPage) {
                alert('起始页不能大于结束页');
                return;
            }

            if (endPage > 1000) {
                alert('最大页数不能超过1000');
                return;
            }

            fetch(`${API_PREFIX}/start`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    category_url: categoryUrl,
                    start_page: startPage,
                    end_page: endPage
                })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    addLog('任务启动成功', 'success');
                    // 修复：传入两个参数，启动时isCompleted为false
                    updateButtonStates(true, false);
                } else {
                    addLog('启动失败: ' + data.message, 'error');
                }
            })
            .catch(error => {
                addLog('启动失败: ' + error.message, 'error');
            });
        }

        function stopTask() {
            fetch(`${API_PREFIX}/stop`, {
                method: 'POST'
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    addLog('任务已停止', 'warning');
                    // 修复：传入两个参数，停止时isCompleted为false
                    updateButtonStates(false, false);
                } else {
                    addLog('停止失败: ' + data.message, 'error');
                }
            })
            .catch(error => {
                addLog('停止失败: ' + error.message, 'error');
            });
        }

        function exportData() {
            fetch(`${API_PREFIX}/export`)
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    document.getElementById('exportCount').textContent = data.count;
                    document.getElementById('exportFilename').textContent = data.filename;
                    document.getElementById('downloadLink').href = `${API_PREFIX}/download/${data.download_path}`;
                    
                    const modal = new bootstrap.Modal(document.getElementById('downloadModal'));
                    modal.show();
                } else {
                    addLog('导出失败: ' + data.message, 'error');
                }
            })
            .catch(error => {
                addLog('导出失败: ' + error.message, 'error');
            });
        }

        function clearTaskData() {
            // 确认对话框
            if (!confirm('确定要清空所有任务数据吗？\n\n此操作将删除：\n- 所有任务队列\n- 已完成数据\n- 统计信息\n- URL映射\n\n此操作不可恢复！')) {
                return;
            }

            fetch(`${API_PREFIX}/clear`, {
                method: 'POST'
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    addLog('所有任务数据已清空', 'success');
                    // 重置按钮状态
                    updateButtonStates(false, false);
                } else {
                    addLog('清空失败: ' + data.message, 'error');
                }
            })
            .catch(error => {
                addLog('清空失败: ' + error.message, 'error');
            });
        }


        function startStatusUpdates() {
            statusInterval = setInterval(updateStatus, 2000);
        }

        function updateStatus() {
            fetch(`${API_PREFIX}/status`)
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    const status = data.data;
                    updateUI(status);
                }
            })
            .catch(error => {
                console.error('获取状态失败:', error);
            });
        }

        function updateUI(status) {
            // 更新任务状态
            const taskStatusEl = document.getElementById('taskStatus');
            if (status.running) {
                taskStatusEl.textContent = '运行中';
                taskStatusEl.className = 'text-success';
                isTaskRunning = true;
            } else if (status.progress.is_completed) {
                taskStatusEl.textContent = '已完成';
                taskStatusEl.className = 'text-info';
                isTaskRunning = false;
            } else {
                taskStatusEl.textContent = '待机中';
                taskStatusEl.className = 'text-primary';
                isTaskRunning = false;
            }

            // 更新统计数据
            document.getElementById('successPagesRatio').textContent = 
                `${status.progress.success_pages || 0}/${status.progress.total_pages || 0}`;
            document.getElementById('successDetails').textContent = 
                status.progress.success_details || 0;
            document.getElementById('failedDetails').textContent = 
                status.progress.failed_details || 0;
            document.getElementById('totalDetails').textContent = 
                status.progress.total_details || 0;

            // 更新进度条 - 根据(成功详情+失败详情)/总详情计算
            const successDetails = status.progress.success_details || 0;
            const totalDetails = status.progress.total_details || 0;
            const progress = status.progress.progress_percentage || 0;
            const progressBar = document.getElementById('progressBar');
            const progressText = document.getElementById('progressText');
            
            progressBar.style.width = progress + '%';
            progressText.textContent = Math.round(progress) + '%';

            // 更新按钮状态 - 修复：确保传入两个参数
            updateButtonStates(status.running, status.progress.is_completed);

            // 更新日志
            if (status.logs && status.logs.length > 0) {
                const logContainer = document.getElementById('logContainer');
                logContainer.innerHTML = '';
                status.logs.slice(-20).forEach(log => {
                    addLogToContainer(log.message, log.time);
                });
            }
        }

        function updateButtonStates(running, isCompleted) {
            // 任务运行时禁用启动按钮
            document.getElementById('startBtn').disabled = running;
            // 任务运行时启用停止按钮
            document.getElementById('stopBtn').disabled = !running;
            // 导出按钮：只在任务完成后才启用（修复按钮失灵问题）
            document.getElementById('exportBtn').disabled = !isCompleted;
            // 清空按钮：随时可用，不受任务状态限制
            document.getElementById('clearBtn').disabled = false;
        }

        function addLog(message, type = 'info') {
            const logContainer = document.getElementById('logContainer');
            const time = new Date().toLocaleTimeString();
            addLogToContainer(message, time, type);
        }

        function addLogToContainer(message, time, type = 'info') {
            const logContainer = document.getElementById('logContainer');
            const logEntry = document.createElement('div');
            logEntry.className = 'log-entry';
            
            let icon = 'bi-info-circle';
            let color = 'text-muted';
            
            if (type === 'success') {
                icon = 'bi-check-circle';
                color = 'text-success';
            } else if (type === 'error') {
                icon = 'bi-x-circle';
                color = 'text-danger';
            } else if (type === 'warning') {
                icon = 'bi-exclamation-triangle';
                color = 'text-warning';
            }
            
            logEntry.innerHTML = `
                <i class="bi ${icon}"></i> 
                <span class="${color}">[${time}] ${message}</span>
            `;
            
            logContainer.appendChild(logEntry);
            logContainer.scrollTop = logContainer.scrollHeight;
        }

        function clearLogs() {
            document.getElementById('logContainer').innerHTML = '';
            addLog('日志已清空', 'info');
        }
    </script>
</body>
</html>

